﻿using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using MMSWebsite.Models;
using System;
using MMSWebsite.Controllers;

namespace MMSWebsite.DataAccessManagement
{
    public class CustomerAccessProvider : Controller
    {
        MMSEntities _entities = new MMSEntities();
        EmployeeAccessProvider _empProvider = new EmployeeAccessProvider();
        MasterDataAccessProvider _mdatp = new MasterDataAccessProvider();
        #region Add new customer
        /// <summary>
        /// Add new customer
        /// <para>Return true: if add new customer info successfully, 
        /// false: if adding new customer info unsuccessfully</para>
        /// </summary>
        /// <param name="cus">Customer</param>
        /// <returns>true: if add new customer info successfully, 
        /// false: if adding new customer info unsuccessfully</returns>
        public bool AddCus(Customer cus)
        {
            try
            {
                //add information Employee
                var newCuss = new MMS_CUSTOMER
                                  {
                                      Company = cus.CompanyNm,
                                      Tax = cus.Tax,
                                      CusCode = cus.Code,
                                      Birth = cus.Birth,
                                      CusEmail = cus.Email,
                                      CusName = cus.Name,
                                      Phone = cus.Phone,
                                      Sex = cus.Sex,
                                      IdCode = cus.IdCode,
                                      NumberAdddress = cus.NumberAddress
                                  };

                //add address to database
                var area =
                    _entities.MMS_AREAs.FirstOrDefault(
                        x => x.CityName == cus.Area.CityName && x.DistrictName == cus.Area.DistrictName);
                newCuss.MMS_AREA = area;

                //relaion in Emp_Cus
                newCuss.MMS_EMP_CUS_CTRL.Add(new MMS_EMP_CUS_CTRL());

                _entities.AddToMMS_CUSTOMERs(newCuss);
                _entities.SaveChanges();
                return true;
            }
            catch
            {
                return false;
            }

        }
        #endregion Add new customer

        #region Update customer information
        /// <summary>
        /// Update customer information
        /// <para>Return true: if update customer info successfully, 
        /// false: if updating customer info unsuccessfully</para>
        /// </summary>
        /// <param name="customer">Customer</param>
        /// <returns>Return true: if update customer info successfully, 
        /// false: if updating customer info unsuccessfully</returns>
        public bool UpdateCustomer(Customer customer)
        {
            try
            {
                var cus = _entities.MMS_CUSTOMERs.Single(e => e.Id == customer.Id);
                //update base information
                cus.Company = customer.CompanyNm;
                cus.Tax = customer.Tax;
                cus.CusCode = customer.Code;
                cus.CusName = customer.Name;
                cus.IdCode = customer.IdCode;
                cus.CusEmail = customer.Email;
                cus.Phone = customer.Phone;
                cus.Sex = customer.Sex;
                cus.Birth = customer.Birth;
                cus.NumberAdddress = customer.NumberAddress;

                //update address
                var area =
                    _entities.MMS_AREAs.FirstOrDefault(
                        x => x.CityName == customer.Area.CityName && x.DistrictName == customer.Area.DistrictName);
                cus.MMS_AREA = area;
                //emp.MMS_ADDRESS.CityName = customer.Address.CityName;
                //emp.MMS_ADDRESS.DistrictName = customer.Address.DistrictName;
                //emp.MMS_ADDRESS.NumberAdd = customer.Address.NumberAdd;

                _entities.SaveChanges();
                return true;
            }
            catch (Exception ex)
            {
                // To do: handle exception, write log
                return false;
            }
        }
        #endregion Update customer information

        #region Get Customer By Id
        /// <summary>
        /// Get Customer By Id
        /// <para>Return Customer. Caution: Can be empty</para>
        /// </summary>
        /// <param name="id">Customer Id</param>
        /// <returns>Customer</returns>
        public Customer GetCusById(int id)
        {  
            try
            {
                var customer = _entities.MMS_CUSTOMERs.Single(e => e.Id == id);
                return ConvertMMSCusToCusModel(customer);
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        #endregion Get Customer By Id

        #region Get List Of Customer
        /// <summary>
        /// Get List Of Customer
        /// <para>Return List Of Customer. Caution: Can be empty</para>
        /// </summary>
        /// <returns>List Of Customer</returns>
        public List<Customer> GetCusList()
        {
            var lsCus = new List<Customer>();
            try
            {
                var lsCusEntities = _entities.MMS_CUSTOMERs.OrderBy(x=>x.CusName);

                foreach (var entity in lsCusEntities)
                {
                    lsCus.Add(ConvertMMSCusToCusModel(entity));
                }
                return lsCus;
            }
            catch (Exception ex)
            {
                // To do: handle exception, write log
                return lsCus;
            }
        }
        #endregion Get List Of Customer

        #region Get List Of Customer in Allocation Board
        public List<Customer> GetAllocationCus()
        {
            
            var customers = GetCustomerByReviewer(AccountController.EmpAccount.Employee.Id);
            //var customer = GetCusList();
            return customers.Where(x => x.ResponsibleEmp == null && x.Status == null).ToList();

        }
        #endregion Get List Of Customer in Allocation Board

        #region Get List Of Customer in Processing board
        public List<Customer> GetProcessingCus()
        {
            var customers = GetCustomerByReviewer(AccountController.EmpAccount.Employee.Id);
            //var customers = GetCusList();
            return customers.Where(x => x.ResponsibleEmp != null && x.FinishedDay == null && x.Status == null).ToList();
        }
        #endregion Get List Of Customer in Processing board

        #region Get List Of Customer in Processing board
        public List<Customer> GetCheckingCus()
        {
            var customers = GetCustomerByReviewer(AccountController.EmpAccount.Employee.Id);
            //var customers = GetCusList();
            return customers.Where(x => x.ResponsibleEmp != null && x.FinishedDay != null && x.Status == null).ToList();
        }

        #endregion Get List Of Customer in Processing board
        public List<Customer> GetStoreResult()
        {
            var customers = GetCustomerByReviewer(AccountController.EmpAccount.Employee.Id);
            //var customers = GetCusList();
            return customers.Where(x=>x.Status != null).OrderByDescending(x=>x.Id).ToList();
        }
        #region Get List Customer in Store Result

        #endregion

        public List<Customer> GetCusByFV(int idFv)
        {
            var listCus = new List<Customer>();
            var listIDCus =
                _entities.MMS_EMP_CUS_CTRLs.Where(x => x.idEmp == idFv && x.Status == null);
            foreach (var mmsEmpCusCtrl in listIDCus)
            {
                if (mmsEmpCusCtrl.idCus != null) listCus.Add(GetCusById((int) mmsEmpCusCtrl.idCus));
            }

            return listCus;
        }

        public List<Customer> GetCustomerByReviewer(int idReviewer)
        {
            //get all cus of Reviewer
            var cusOfReviwer = _entities.MMS_CUSTOMERs.Where(x => x.MMS_AREA.MMS_GROUP.Responsibility == idReviewer).OrderBy(n=>n.CusName).ToList();
            var list = new List<Customer>();
            foreach (var mmsCustomer in cusOfReviwer)
            {
                list.Add(ConvertMMSCusToCusModel(mmsCustomer));
            }
            return list;
        }

        public Customer ConvertMMSCusToCusModel(MMS_CUSTOMER customer)
        {
            Customer cus = null;
            if (customer != null)
            {
                var mmsEmpCusCtrl = customer.MMS_EMP_CUS_CTRL.LastOrDefault();
                var responsibleEmpId = mmsEmpCusCtrl != null ? mmsEmpCusCtrl.idEmp : null;
                DateTime? startday, endday, finishedday;

                if (mmsEmpCusCtrl.startDate == null) startday = null;
                else startday = mmsEmpCusCtrl.startDate;

                if (mmsEmpCusCtrl.endDate == null) endday = null;
                else endday = mmsEmpCusCtrl.endDate;

                if (mmsEmpCusCtrl.finishedDate == null) finishedday = null;
                else finishedday = mmsEmpCusCtrl.finishedDate;

                cus = new Customer
                {
                    CompanyNm = customer.Company,
                    Tax = customer.Tax,
                    Code = customer.CusCode,
                    Id = customer.Id,
                    Name = customer.CusName,
                    IdCode = customer.IdCode,
                    Email = customer.CusEmail,
                    Phone = customer.Phone,
                    Sex = customer.Sex,
                    Birth = customer.Birth,
                    NumberAddress = customer.NumberAdddress,
                    Area = customer.MMS_AREA,
                    ResponsibleEmp = responsibleEmpId == null ? null : _empProvider.GetEmployeeById(responsibleEmpId),
                    //StartDay = DateTime.ParseExact(startday.Value.ToShortDateString(), "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture),
                    Status = mmsEmpCusCtrl.Status == null ? null: _mdatp.GetMDById((int) mmsEmpCusCtrl.Status),
                    StartDay = startday,
                    EndDay = endday,
                    FinishedDay = finishedday
                };
            }
            return cus;
        }


    }
}